﻿using System;
using FarseerGames.FarseerPhysics.Collisions;
using FarseerGames.FarseerPhysics.Dynamics;
using FarseerGames.FarseerPhysics.Factories;
using FarseerGames.FarseerPhysics.Mathematics;
using FreeGoo.GameEngine.Renderables.Particles.Keys;

namespace FreeGoo.GameEngine.Renderables.Particles
{
    public static class ParticleFactory
    {
        public const float DefaultSimpleParticleRadius = 8;
        public const float DefaultHookParticleRadius = DefaultSimpleParticleRadius;
        public const float DefaultMultiLinkParticleRadius = DefaultSimpleParticleRadius;
        public const float DefaultChainParticleRadius = DefaultSimpleParticleRadius * 0.8f;
        public const float DefaultRopeParticleRadius = DefaultChainParticleRadius;
        public const float DefaultBalloonParticleRadius = DefaultSimpleParticleRadius * 1.2f;
        public const float DefaultStrongParticleRadius = DefaultSimpleParticleRadius * 1.2f;
        public const float DefaultKeyParticleRadius = DefaultSimpleParticleRadius * 0.5f;
        public const float BalloonDensityFactor = 1f / 5f;
        public const int ParticleEdges = 8;
        public const float BalloonBuoyancy = 4f;
        public static readonly float Density = MixedFactory.Density;

        public static Particle CreateSimpleParticle(Engine engine, Vector2 position, float radius)
        {
            Body body = BodyFactory.Instance.CreateCircleBody(radius, (float)(Density * Math.PI * radius * radius));
            body.Position = position;
            Geom geom = GeomFactory.Instance.CreateCircleGeom(body, radius, ParticleEdges);

            Particle particle = new Simple(
                geom,
                radius);
            engine.Add(particle);
            return particle;
        }

        public static Particle CreateMultiLinkParticle(Engine engine, Vector2 position, float radius)
        {
            Body body = BodyFactory.Instance.CreateCircleBody(radius, (float)(Density * Math.PI * radius * radius));
            body.Position = position;
            Geom geom = GeomFactory.Instance.CreateCircleGeom(body, radius, ParticleEdges);

            Particle particle = new MultiLink(
                geom,
                radius);
            engine.Add(particle);
            return particle;
        }

        public static Particle CreateStrongParticle(Engine engine, Vector2 position, float radius)
        {
            Body body = BodyFactory.Instance.CreateCircleBody(radius, (float)(Density * Math.PI * radius * radius));
            body.Position = position;
            Geom geom = GeomFactory.Instance.CreateCircleGeom(body, radius, ParticleEdges);

            Particle particle = new Strong(
                geom,
                radius);
            engine.Add(particle);
            return particle;
        }

        public static Chain CreateChainParticle(Engine engine, Vector2 position, float radius)
        {
            Body body = BodyFactory.Instance.CreateCircleBody(radius, (float)(Density * Math.PI * radius * radius));
            body.Position = position;
            Geom geom = GeomFactory.Instance.CreateCircleGeom(body, radius, ParticleEdges);

            Chain particle = new Chain(
                geom,
                radius);
            engine.Add(particle);
            return particle;
        }

        public static Rope CreateRopeParticle(Engine engine, Vector2 position, float radius)
        {
            Body body = BodyFactory.Instance.CreateCircleBody(radius, (float)(Density * Math.PI * radius * radius));
            body.Position = position;
            Geom geom = GeomFactory.Instance.CreateCircleGeom(body, radius, ParticleEdges);

            Rope particle = new Rope(
                geom,
                radius);
            engine.Add(particle);
            return particle;
        }

        public static Balloon CreateBalloonParticle(Engine engine, Vector2 position, float radius, float buoyancy)
        {
            Body body = BodyFactory.Instance.CreateCircleBody(radius, (float)(Density * Math.PI * radius * radius * BalloonDensityFactor));
            body.Position = position;
            Geom geom = GeomFactory.Instance.CreateCircleGeom(body, radius, ParticleEdges);

            Balloon particle = new Balloon(
                geom,
                radius,
                (float)(buoyancy * Density * Math.PI * radius * radius));
            engine.Add(particle);
            return particle;
        }

        public static Balloon CreateBalloonParticle(Engine engine, Vector2 position, float radius)
        {
            return CreateBalloonParticle(engine, position, radius, BalloonBuoyancy);
        }

        public static FixedHook CreateFixedHookParticle(Engine engine, Vector2 position, float radius)
        {
            Body body = BodyFactory.Instance.CreateCircleBody(radius, (float)(Density * Math.PI * radius * radius));
            body.Position = position;
            Geom geom = GeomFactory.Instance.CreateCircleGeom(body, radius, ParticleEdges);

            FixedHook particle = new FixedHook(
                geom,
                radius);
            engine.Add(particle);
            return particle;
        }

        public static Particle CreateMotorParticle(FreeGoo.GameEngine.Engine engine, Vector2 vector2, int connectorCount, int cornerCount)
        {
            return null;
        }

        public static KeyedMotorKey CreateKeyedMotorKey(Engine engine, Vector2 position, float radius)
        {
            Body body = BodyFactory.Instance.CreateCircleBody(radius, (float)(Density * Math.PI * radius * radius));
            body.Position = position;
            Geom geom = GeomFactory.Instance.CreateCircleGeom(body, radius, ParticleEdges);

            KeyedMotorKey particle = new KeyedMotorKey(
                geom,
                radius);
            engine.Add(particle);
            return particle;
        }
    }
}
